#include "AudioRecordThread.h"
#include "FilePicker.h"
#include "DeviceTool.h"

void AudioRecordThread::run() {
    const AVInputFormat *fmt = av_find_input_format("avfoundation");
    if (!fmt) {
        emit this->recordState(AudioRecordFail);
        return;
    }
    // 格式上下文
    AVFormatContext *ctx = nullptr;
    // 打开设备
    int ret = avformat_open_input(&ctx, ":0", fmt, nullptr);
    if (ret < 0) {
        char errbuf[1024] = {0};
        av_strerror(ret, errbuf, sizeof(errbuf));
        qDebug() << "打开设备失败" << errbuf;
        emit this->recordState(AudioRecordFail);
        return;
    }
    QString recordPath = FilePicker::locationPath(DesktopDir).append("/record/").append(QDateTime::currentDateTime().toString("yyyy_MM_dd_HHmmss"));
    DeviceInfo devInfo = DeviceTool::gainDeviceInfo(ctx);
    QFile recordFile(recordPath.append(".wav"));

    // const AVCodec *codec = avcodec_find_decoder(AV_CODEC_ID_AAC);
    // //  找不到编码器
    // if (codec == nullptr) {
    //     return;
    // }

    // //  创建编码上下文
    // AVCodecContext *codecCtx = avcodec_alloc_context3(codec);
    // if (codecCtx == nullptr) {
    //     return;
    // }
    // codecCtx->sample_rate = deviceInfo->sampleRate;
    // codecCtx->sample_fmt = (AVSampleFormat)deviceInfo->format;
    // codecCtx->ch_layout.nb_channels = deviceInfo->ch_layout.nb_channels;
    // codecCtx->bit_rate = deviceInfo->bit_rate;

    // if (avcodec_open2(codecCtx, codec, nullptr) < 0) {
    //     avcodec_free_context(&codecCtx);
    //     //  打开编码器失败
    //     return;
    // }

    // //  存放编码后的数据
    // AVPacket *aacPkt = av_packet_alloc();
    // if (aacPkt == nullptr) {
    //     avcodec_free_context(&codecCtx);
    //     return;
    // }

    // WriteOnly：只写模式。如果文件不存在，就创建文件；如果文件存在，就删除文件内容
    if (!recordFile.open(QFile::WriteOnly)) {
        qDebug() << "文件打开失败" << recordPath;
        avformat_close_input(&ctx);
        emit this->recordState(AudioRecordFail);
        return;
    }
    WAVHeader header = WAVHeader();
    header.numChannels = devInfo.numChannels;
    header.sampleRate = devInfo.sampleRate;
    header.bitsPerSample = devInfo.bitsPerSample;
    if (devInfo.codecId >= AV_CODEC_ID_PCM_F32BE) {
        header.audioFormat = 3;
    }
    header.blockAlign = header.bitsPerSample * header.numChannels >> 3;
    header.byteRate = header.sampleRate * header.blockAlign;
    recordFile.write((const char *)&header, sizeof(WAVHeader));

    emit this->recordState(AudioRecording);
    emit AudioRecordThread::recordDuration(duration);
    //  录制的长度
    uint32_t recordSize = 0;
    // 数据包
    AVPacket *pkt = av_packet_alloc();
    while (!isInterruptionRequested()) {
        ret = av_read_frame(ctx, pkt);
        if (ret == 0) {
            // 写入数据

            recordFile.write((const char *) pkt->data, pkt->size);
            // if (this->encode(codecCtx, pkt, aacPkt, recordFile) < 0) {
            //     continue;
            // }

            // this->encode(codecCtx, pkt, aacPkt, recordFile);

            recordSize += pkt->size;
            int currentDura = recordSize / devInfo.bit_rate;
            if (currentDura != duration) {
                duration = currentDura;
                emit AudioRecordThread::recordDuration(duration);
            }
            // 释放资源
            av_packet_unref(pkt);
        }else if (ret == AVERROR(EAGAIN)) {//资源临时不可用
            continue;
        }else {
            char errbuf[1024] = {0};
            av_strerror(ret, errbuf, sizeof(errbuf));
            qDebug() << "av_read_frame error" << errbuf << ret;
            break;
        }
    }
    emit this->recordState(AudioRecordEnd);

    uint32_t riffChunkDataSize = recordSize + sizeof(WAVHeader) - sizeof(header.riffChunkId) - sizeof(header.riffChunkDataSize);
    recordFile.seek(sizeof(header.riffChunkId));
    recordFile.write((const char *)&riffChunkDataSize, sizeof(riffChunkDataSize));
    uint32_t dataChunkDataSize = recordSize;
    recordFile.seek(sizeof(WAVHeader) - sizeof(header.dataChunkDataSize));
    recordFile.write((const char *)&dataChunkDataSize, sizeof(dataChunkDataSize));

    /// 释放资源
    av_packet_free(&pkt);
    //  关闭设备
    avformat_close_input(&ctx);
    /// 关闭文件
    recordFile.close();
    return;
}

// int AudioRecordThread::encode(AVCodecContext *ctx, AVPacket *pkt, AVPacket *aacPkt, QFile &outFile) {
//     //  发送数据到编码器
//     int ret = avcodec_send_packet(ctx, pkt);

//     if (ret < 0) {
//         return ret;
//     }

//     while (true) {
//         ret = avcodec_receive_packet(ctx, aacPkt);
//         if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
//             //  继续读取数据到frame，然后发送到编码器
//             return 0;
//         } else if (ret < 0) {
//             return ret;
//         }
//         //  成功从编码器拿到编码后的数据
//         //  将编码后的数据写入文件
//         outFile.write((char *)aacPkt->data, aacPkt->size);
//         av_packet_unref(aacPkt);
//     }

// }

AudioRecordThread::~AudioRecordThread() {
    qDebug() << this << "录音线程销毁了";
}
